gusucode.com > VC++ RingSDK界面库 > VC++ RingSDK界面库/code/libsrc/ringdows/ringdockbar.cpp

    /**********************************************************************
//
//
//        ##########                          ######  #########   # ######    #
//      #############                      ########### ######### #########  ###
//     ######## # ###  ##                 ############# ##    ## #####  # ####
//     ####  ##    ## ###                 ###     ### # #      #####   #####
//          #     ###  #            #     ##       ##  ##      ##     ###
//         ## ###### ##      ##  ####    ####          #       #     ##
//       #########  ###  ## ### #######   ######      ##      ##    ###
//      ######      ##  ######  ##  ##       ####     #      ##     ####
//     #######     ##   ###### ##  ###          ##   ##     ###    ######
//     #########   ##  ###### ## ######         ### ##    ###      #  #####
//    ##    ###### ####### ### #### ##  ## #######  ########      ##    ####
//    ##      #### ###  #  ### ### ##  ##########   ######       ##      ####
//   ##         ##                ##   #########    ####         #         ##
//               #              ###
//                              ##
//                             ###
//                             ##
//
//
//							临风程序界面类库 ringdows.lib
//作者:临风
//
//版本:0.2
//
//声明:本类库可以自由使用而不须对作者作出任何回报,但作者希望能得到
//		  你的鼓励和支持。你可以对类库源码作出修改和改进,但希望你能在
//		  修改的同时给作者一份同样的副本。
//		  本类库不得用于任何商业用途,如确实需要,请与作者联系。
//
//e-mail:ringphone@sina.com
//
//原文件名:ctrlbar.cpp
//
//本文件说明:停靠栏实现代码,类似IE可移动的菜单栏及工具栏
//
//设计思路:
//		RingSDK设计成任意控件,子窗口均可停靠,停靠栏并非窗口,仅包含
//	这些可停靠窗口停靠,拖动时的一些信息及处理窗口的停靠和拖动,绘制
//	窗口的拖动把手等。当窗口为浮动状态时会创建浮动栏窗口,容纳停靠
//	窗口。浮动栏必须自适应停靠窗口尺寸。
//
//	停靠实现:
//		主窗口四边会根据需要创建停靠容器栏,停靠窗口是停靠在
//	容器栏,工具栏,状态栏设计成必须停靠(默认无法拖动,必须调用
//	EnableDock才可拖动),这样设计是方便计算主窗口客户区尺寸,扣掉
//	四个停靠容器栏尺寸即可。
//
//	绘制实现:
//		停靠容器栏会调用DockBar::Draw绘制背景,把手,停靠栏边框,而
//	在浮动状态,FlyBar浮动栏不调用该函数,因此无边框及把手。
//
//	拖动实现:
//		开始拖动时需要初始化3个矩形:横向和纵向停靠矩形(边框宽度为1),
//	浮动矩形(边框宽度为3),拖动时根据鼠标位置偏移这些矩形并随时调整,
//	判断停靠位置决定显示哪个矩形。
//	
//	主窗口尺寸变动响应:
//		主窗口尺寸变动,停靠容器栏进行停靠窗口的重新排列,按行依次查询
//	每一停靠栏前面空位尺寸,获取到整行可调整位置空间尺寸,然后调用
//	行内最后一个停靠栏的AdjustDockPos调整停靠窗口位置,停靠窗口如果
//	调整后与前面窗口重叠,会调用前一个停靠栏的该函数引起连锁反应直到
//	行内窗口全部调整完毕。
//
//	停靠窗口尺寸响应:
//		停靠窗口尺寸变动(工具栏,菜单栏增删按钮等)由工具栏通知停靠栏,
//	停靠栏更新尺寸后通知父窗口,父窗口响应后产生主窗口尺寸变动事件,导致
// 主窗口尺寸变动响应。
**********************************************************************/

#define MAKE_SELF_LIB
#include "ringdows.h"

DWORD	gdwDockBarId = 39000;

RingFlyBar::RingFlyBar(RingBaseWnd* parent)
{
   SetParentObj(parent);
   m_child = NULL;
	m_dragger = NULL;
	SetAutoDelete();
   m_windowType = ITIS_FLYBAR;
}

RingFlyBar::~RingFlyBar()
{
	if(m_child && m_child->m_State == TBS_FLAG_FLY)
		delete m_child;
}

BOOL RingFlyBar::Create(LPCTSTR lpszTitle)
{
   if(m_hWnd)
		return TRUE;

	if(!Register("RingFlyBar",
		(HBRUSH)(COLOR_BTNFACE + 1),
		NULL,
		NULL,
		m_windowInfo.hCursor,
		NULL))
		return NULL;
	
   CreateEx(lpszTitle,"RingFlyBar",//0x94CC1200, 
		WS_POPUPWINDOW | WS_CAPTION | WS_THICKFRAME | 
		/*WS_OVERLAPPED |*/ WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
		WS_EX_TOOLWINDOW,NULL,NULL);//,0,0,0,0);
	
   RingMenu rm;
	rm.Attach(GetSystemMenu(m_hWnd,FALSE));
	//rm.Delete(SC_CLOSE);
	//rm.Delete(SC_SIZE);
	rm.Delete(SC_MINIMIZE);
	rm.Delete(SC_MAXIMIZE);
	rm.Delete(SC_MOVE);
	rm.Delete(SC_RESTORE);

	return (BOOL)m_hWnd;
}

LRESULT RingFlyBar::RingdowProc(HWND hWnd,RINGPARAMS param)
{
	if(param.uMsg >= WM_KEYFIRST && param.uMsg <= WM_KEYLAST)
	{
		//消息转发给子窗口
		if(m_child && m_child->GetChild())
			return SendMessage(m_child->GetChild()->Handle(),param);
		else
			return DefaultProc(param);
	}
	switch(param.uMsg)
   {
		case WM_COMMAND:
			//消息转发给父窗口
			if(m_child && m_child->GetChild())
				return SendMessage(m_child->GetChild()->Parent()->Handle(),param);
			else
				return DefaultProc(param);
		case WM_CONTEXTMENU:
			//取消弹出菜单
			//if(HIWORD(lParam))
			//PostMessage(hWnd,WM_CANCELMODE,0,0);
			return 0;
		case WM_SHOWWINDOW:
			if(param.wParam)
			{				
				Update();
			}
			return DefaultProc(param);
		case WM_PAINT:
			//检测子窗口显示状态,不允许外力干预(调用者或外挂)
			if(m_child && m_child->GetChild() && !m_child->GetChild()->IsVisible())
				m_child->GetChild()->Show();
			return DefaultProc(param);
		case WM_CLOSE:
      	Show(SW_HIDE);
			if(m_child && m_child->m_pSite)
				m_child->m_pSite->OnDockBarHide(m_child);
         break;
      case WM_ACTIVATE:
         if(IsWindowEnabled(hWnd))
         {
	         SendMessage(m_parent->Handle(),WM_NCACTIVATE,TRUE,0);
   		   SendMessage(m_hWnd,WM_NCACTIVATE,TRUE,0);
         }
         break;
		case WM_NOTIFY:
			switch(param.lpnmhdr->code)
			{
			case TTN_NEEDTEXT:
				{
					((LPTOOLTIPTEXT)param.lParam)->hinst = GetInstance();
					return SendMessage(m_parent->Handle(),WM_RINGTOOLTIP,((LPTOOLTIPTEXT)param.lParam)->hdr.idFrom,param.lParam);
				}
				
				//case TBN_DROPDOWN:
				//工具栏DropDown按钮
				//	return SendMessage(param.lpnmhdr->hwndFrom,param);
			}
			if(IsWindowPtr(m_parent))
				return SendMessage(m_parent->Handle(),WM_NOTIFY,param.wParam,param.lParam);
			return DefaultProc(param);
      case WM_NCLBUTTONDBLCLK:
			if(param.wParam == HTCAPTION)
         {
				if(m_child)
					m_child->DockBack();
			}
			return 0;
		case WM_NCLBUTTONDOWN:
         if(param.wParam == HTCAPTION)
         {
				if(m_child)
				{
					POINT pt = {param.mousept.x,param.mousept.y};
					RingDockSite* pSite = m_child->m_pSite;
					if(pSite == NULL && m_child->m_child)
						pSite = ((RingWnd*)(m_child->GetChild()->Parent()))->CreateDockSite(TBS_FLAG_DOCKTOP);

					if(pSite == NULL)
						return 0;

					if(m_dragger == NULL)
						m_dragger = &pSite->m_dragger;
					
					ScreenToClient(m_hWnd,&pt);
					
					param.mousept.x = (short)pt.x;
					param.mousept.y = (short)pt.y;
					m_child->StartDrag(m_hWnd,m_dragger,param);
				}
            return 0;
         }
         else
         	return DefaultProc(param);
		case WM_MOUSEMOVE:
			if(m_dragger && m_dragger->IsDragging() && m_child)
				return m_child->OnDrag(m_hWnd,m_dragger,param);
			return DefaultProc(param);
		case WM_LBUTTONUP:
			if(m_dragger && m_dragger->IsDragging() && m_child)
				return m_child->StopDrag(m_child->GetChild()->Parent()->Handle(),m_dragger,param);
			return DefaultProc(param);
		/*case WM_ERASEBKGND:
			if(!DrawBkg(param.hdc))
				DefaultProc(param);
			break;
		*/
		case WM_SIZE:
			//NotifyChild(hWnd,param.uMsg,param.wParam,param.lParam);
			if(m_child)
			{
				m_child->UpdateFlySize(param.mousept.x + WINVAR_FRAME_X*2,
												param.mousept.y + BARTOOLY + WINVAR_FRAME_Y);
				/*if(m_child->m_child)
				{
					RECT rc;
					GetWindowRect(m_child->m_child->Handle(),&rc);
					OffsetRect(&rc,-rc.left,-rc.top);
					m_child->UpdateSize(rc.right,rc.bottom,FALSE);
				}
				*/
			}
			break;
		case WM_SIZING:
		{
			RECT rctmp;
			LPRECT lprc = (LPRECT)param.lParam;
						
			CopyRect(&rctmp,lprc);
			param.lParam = (LPARAM)&rctmp;
			InflateRect(&rctmp,-WINVAR_FRAME_X,-WINVAR_FRAME_Y);
			rctmp.top += (BARTOOLY);// - WINVAR_FRAME_Y);
			
			if(m_child)
				m_child->OnSizing(param);
			//SendMessage(GetChild(),param);
			InflateRect(&rctmp,WINVAR_FRAME_X,WINVAR_FRAME_Y);
			rctmp.top -= (BARTOOLY);// - WINVAR_FRAME_Y);
			param.lParam = (LPARAM)lprc;
			CopyRect(lprc,&rctmp);
			return DefaultProc(param);
			/*
			switch(param.wParam)
			{
				case WMSZ_LEFT:
					lprc->left = lprc->right - rc.right - WINVAR_FRAME_X*2;
					break;
				case WMSZ_RIGHT:
					lprc->right = lprc->left + rc.right + WINVAR_FRAME_X*2;
					break;
				case WMSZ_TOP:
					lprc->top = lprc->bottom - rc.bottom - BARTOOLY - WINVAR_FRAME_Y - 2;
					break;
				case WMSZ_TOPLEFT:
					lprc->top = lprc->bottom - rc.bottom - BARTOOLY - WINVAR_FRAME_Y - 2;
					lprc->left = lprc->right - rc.right - WINVAR_FRAME_X*2;
					break;
				case WMSZ_TOPRIGHT:
					lprc->top = lprc->bottom - rc.bottom - BARTOOLY - WINVAR_FRAME_Y - 2;
					lprc->right = lprc->left + rc.right + WINVAR_FRAME_X*2;
					break;
				case WMSZ_BOTTOM:
					lprc->bottom = lprc->top + rc.bottom + BARTOOLY + WINVAR_FRAME_Y + 2;
					break;
				case WMSZ_BOTTOMLEFT:
					lprc->left = lprc->right - rc.right - WINVAR_FRAME_X*2;
					lprc->bottom = lprc->top + rc.bottom + BARTOOLY + WINVAR_FRAME_Y + 2;
					break;
				case WMSZ_BOTTOMRIGHT:
					lprc->right = lprc->left + rc.right + WINVAR_FRAME_X*2;
					lprc->bottom = lprc->top + rc.bottom + BARTOOLY + WINVAR_FRAME_Y + 2;
					break;
			}*/			
		}
      default:
		{	
			LRESULT res = CtlColorProc(hWnd,param);
			if(res != RM_NOTPROCESS)
				return res;
			else
				return DefaultProc(param);
		}
   }
   return 0;
}
/*
BOOL RingFlyBar::DrawBkg(HDC hDC,LPRECT lprc/*=NULL/)
{
	RingDockSite* tmp = NULL;
	
	if(m_child == NULL)
		return FALSE;

	RingWnd* pa = (RingWnd*)m_child->m_parent;

	for(int i=0;i<4;i++)
	{
		tmp = pa->GetDockSite(i);
		if(tmp)
			break;
	}
	
	if(tmp)
	{
		RECT rc;
		::GetClientRect(m_hWnd,&rc);
		ClientToScreen(m_hWnd,(LPPOINT)&rc);
		ClientToScreen(m_hWnd,(LPPOINT)&rc+1);
		ScreenToClient(pa->Handle(),(LPPOINT)&rc);
		ScreenToClient(pa->Handle(),(LPPOINT)&rc+1);
		//CopyRect(&rc,(LPRECT)&m_winpos);
		if(lprc)
			CopyRect(lprc,&rc);
		//OffsetRect(&rc,tmp->m_winpos.x,tmp->m_winpos.y);
		return tmp->DrawBkg(hDC,&rc);			
	}
	return FALSE;
}
*/
BOOL RingFlyBar::OnParentNotify(HWND hWnd,UINT uMsg,UINT wParam,LONG)
{
   if(hWnd == m_parent->Handle() && IsWindowVisible(m_hWnd))
		if(uMsg == WM_ENABLE)
      {
       	EnableWindow(m_hWnd,(BOOL)wParam);
         if(wParam)
   	   	SendMessage(m_hWnd,WM_NCACTIVATE,TRUE,0);
         else
         {
         	SendMessage(m_hWnd,WM_NCACTIVATE,FALSE,0);
            SendMessage(m_parent->Handle(),WM_NCACTIVATE,FALSE,0);
         }
      }
		//else if(uMsg == WM_SIZE)
		//	InvalidateRect(m_hWnd,NULL,TRUE);

	return FALSE;
}

void RingFlyBar::AddChild(RingDockBar* child)
{
	if(child)
	{
		m_child = child;
		
		RingBaseWnd *pwnd = child->GetChild();
		if(pwnd == NULL)
			return;

		if(child->IsMenuBar())
		{
			RingMenu rm;
			rm.Attach(GetSystemMenu(m_hWnd,FALSE));
			rm.EnableItem(SC_CLOSE,FALSE);			
		}
		pwnd->SetParent(m_hWnd);
		pwnd->SetPos(0,0);
	}
}

void RingFlyBar::Update()
{
	if(m_child)
	{
		RECT rc;
		RingBaseWnd* wnd = m_child->GetChild();
		
		if(wnd)
		{
			GetWindowRect(wnd->Handle(),&rc);
			OffsetRect(&rc,-rc.left,-rc.top);
			if(m_child->IsSizeBar())
				SetPos(0,0,rc.right,rc.bottom,0,SWP_NOMOVE);
			else
				SetPos(0,0,rc.right + 2 + WINVAR_FRAME_X*2,
						rc.bottom + 2 + BARTOOLY + WINVAR_FRAME_Y,0,SWP_NOMOVE);
		}
	}
}

void RingFlyBar::UpdateDockSite()
{
	if(m_child)
	{
		RingBaseWnd* pwnd = m_child->GetChild();
		if(pwnd)
		{
			SendMessage(pwnd->Handle(),WM_DOCKSTATECHANGE,
					MAKELONG(TBS_FLAG_FLY,TBS_FLAG_FLY),(LPARAM)pwnd->Handle());			
			Update();
			InvalidateRect(pwnd->Handle(),NULL,FALSE);
		}
	}
}

//////////////////////////////////////////////////////////
//
//	RingDockBar
//
//////////////////////////////////////////////////////////
RingDockBar::RingDockBar()
{
	m_State = TBS_FLAG_NONE;
	m_uStyle = TBS_EX_NONE;
	m_id = gdwDockBarId ++;

	SetRectEmpty(&m_rcDockPos);
	SetRectEmpty(&m_rcClient);
	SetRectEmpty(&m_hrc);
	SetRectEmpty(&m_vrc);
	SetRectEmpty(&m_frc);
	SetRectEmpty(&m_lfrc);
	SetRectEmpty(&m_ldrc);

	m_pSite = NULL;
	m_next = m_prev = NULL;
	m_lineInfo = NULL;
	m_flyBar = NULL;
	m_BorderSpace = 3;
	m_GripperSpace = 9;
	m_bNCBtDown = FALSE;
	m_nSize = 0;
	m_child = NULL;
	m_szTitle = NULL;
	m_nTitleSize = 0;
	m_bVisible = TRUE;
}

RingDockBar::~RingDockBar()
{
	if(m_szTitle)
		Del(m_szTitle);
}

void RingDockBar::SetDockStyle(UINT style)
{
	m_uStyle = style;
	//SizeBar允许TBS_EX_NONE与TBS_EX_CANCLOSE并存,因此这里判断顺序不可搞错
	if(style & TBS_EX_NONE)
	{
		m_GripperSpace = 0;
		if(style & TBS_EX_ALLLINE)
			m_BorderSpace = 2;
		else
			m_BorderSpace = 0;
	}
	else
	{
		m_GripperSpace = 9;
		m_BorderSpace = 3;
	}		

	if((style & TBS_EX_CANCLOSE))
		m_GripperSpace = 15;
}

BOOL RingDockBar::GetDockRect(LPRECT lprc)
{
	if(lprc && m_child && m_pSite)
	{
		if(m_State == TBS_FLAG_FLY)
		{
			if(m_flyBar)
			{
				GetWindowRect(m_flyBar->Handle(),lprc);
				MapWindowPoints(m_flyBar->Handle(),m_pSite->Parent()->Handle(),(LPPOINT)lprc,2);
				return TRUE;
			}
		}
		else
		{
			CopyRect(lprc,&m_rcDockPos);
			MapWindowPoints(m_pSite->Handle(),m_pSite->Parent()->Handle(),(LPPOINT)lprc,2);
			return TRUE;
		}
	}
	return FALSE;
}

//得到指定停靠位置的客户坐标
BOOL RingDockBar::GetClientRect(int state,LPRECT lprc)
{
	if(m_child && lprc)
	{
		LONG x = 0;
		//先向父窗口查询
		NMHDR hdr;
		hdr.hwndFrom = m_child->Handle();
		hdr.code = state;
		hdr.idFrom = (UINT)m_child;

		if(m_pSite)
			x = SendMessage(m_pSite->Parent()->Handle(),WM_GETDRAGRECTS,
									(WPARAM)lprc,(LPARAM)&hdr);
		else if(m_flyBar)
			x = SendMessage(m_flyBar->Parent()->Handle(),WM_GETDRAGRECTS,
									(WPARAM)lprc,(LPARAM)&hdr);
		//查询失败,向控件查询
		if(x == 0)
			x = SendMessage(m_child->Handle(),WM_GETDRAGRECTS,(WPARAM)lprc,(LPARAM)&hdr);
		//再失败,获取控件尺寸处理
		if(x == 0)
		{
			if(m_flyBar && IsWindow(m_flyBar->Handle()))
				m_flyBar->GetClientRect(lprc);
			else
				GetWindowRect(m_child->Handle(),lprc);
		}
		return TRUE;
	}
	else
		return FALSE;
}

LPRECT RingDockBar::GetDragRects(int state)
{
	if(!GetClientRect(state,&m_rcCurr))
		CopyRect(&m_rcCurr,&m_rcDockPos);

	//OffsetRect(&m_rcCurr,-m_rcCurr.left,-m_rcCurr.top);

	if(state == TBS_FLAG_FLY)
	{
		if(!IsSizeBar())
		{
			m_rcCurr.top -= BARTOOLY;
			m_rcCurr.bottom += WINVAR_FRAME_Y;
			m_rcCurr.left -= WINVAR_FRAME_X;
			m_rcCurr.right += WINVAR_FRAME_X;
		}
	}
	else
	{
		InflateRect(&m_rcCurr,m_BorderSpace,m_BorderSpace);

		if(::IsVert(state))
			m_rcCurr.top -= m_GripperSpace + m_BorderSpace;
		else
			m_rcCurr.left -= m_GripperSpace + m_BorderSpace;
	}
	OffsetRect(&m_rcCurr,m_rcDockPos.left-m_rcCurr.left,m_rcDockPos.top-m_rcCurr.top);
	return &m_rcCurr;
}

BOOL RingDockBar::SetChild(RingBaseWnd* child)
{
	if(child && child->IsWindow() && child->Parent() != child && m_child == NULL)
	{
		m_child = child;
		//UpdateClientSize();
		if(m_child->GetWindowType() == ITIS_STATUSBAR)
		{
			m_BorderSpace = 0;
			m_GripperSpace = 0;
		}
		return TRUE;
	}
	return FALSE;
}

BOOL RingDockBar::IsVisible(BOOL *lpbUpdate)
{
	if(lpbUpdate == NULL)	//不检查,直接返回状态值
		return m_bVisible;

	if(m_child && m_child->IsVisible() != m_bVisible)
	{
		m_bVisible = m_child->IsVisible();
		*lpbUpdate = TRUE;
	}
	else
		*lpbUpdate = FALSE;

	return m_bVisible;
}

//获取停靠窗口尺寸,更新m_rcClient,根据m_rcDockPos的停靠位置平移到适当位置
void RingDockBar::UpdateClientSize()
{
	if(m_child)
	{
		RECT rc;
		GetWindowRect(m_child->Handle(),&rc);
		
		if(IsVert())
			OffsetRect(&rc,m_rcDockPos.left + m_BorderSpace - rc.left,
							m_rcDockPos.top + m_BorderSpace + m_GripperSpace - rc.top);
		else
			OffsetRect(&rc,m_rcDockPos.left + m_BorderSpace + m_GripperSpace - rc.left,
							m_rcDockPos.top + m_BorderSpace - rc.top);
		CopyRect(&m_rcClient,&rc);
	}	
}

//客户区尺寸改变,获取停靠窗口尺寸,更新m_rcClient和m_rcDockPos(不更新位置信息)
void RingDockBar::UpdateSize()
{
	UpdateClientSize();

	if(IsVert())
		m_nSize = m_rcClient.right - m_rcClient.left + m_BorderSpace*2;
	else
		m_nSize = m_rcClient.bottom - m_rcClient.top + m_BorderSpace*2;
	
	m_rcDockPos.right = m_rcClient.right + m_BorderSpace;
	m_rcDockPos.bottom = m_rcClient.bottom + m_BorderSpace;

	if(m_lineInfo)
		m_lineInfo->m_maxSize = max(m_lineInfo->m_maxSize,m_nSize);
}

//更新浮动状态下的尺寸,本函数由FlyBar的WM_SIZE消息调用
void RingDockBar::UpdateSize(int nWidth,int nHeight,BOOL bUpdate)
{
/*	m_winpos.cx = nWidth;
	m_nSize = m_winpos.cy = nHeight + m_BorderSpace*2;
	m_rcClient.right = m_rcClient.left + nWidth - m_GripperSpace - m_BorderSpace*2;
	m_rcClient.bottom = m_rcClient.top + nHeight;
	m_winpos.right = m_winpos.x + nWidth;
	m_winpos.bottom = m_winpos.y + m_winpos.cy;
*/
}

void RingDockBar::UpdateFlySize(int nWidth,int nHeight)
{
	m_frc.right = m_frc.left + nWidth;
	m_frc.bottom = m_frc.top + nHeight;
}

//更新所有DockBar或更新FlyBar
void RingDockBar::UpdateAllSite()
{
	if(IsFloat())
	{
		if(m_flyBar && m_flyBar->IsVisible())
			m_flyBar->UpdateDockSite();
	}
	else if(m_pSite)
		m_pSite->UpdateAllSite();
}

BOOL RingDockBar::SetDockTitle(LPCTSTR lpszTitle)
{
	if(lpszTitle == NULL)
		return FALSE;

	LPSTR szTitle;
	int cch = strlen(lpszTitle);

	if(m_szTitle == NULL || cch > m_nTitleSize)
	{		
		m_nTitleSize = cch + 2;
		szTitle = (LPSTR)New(m_nTitleSize);
		if(szTitle)
		{
			Del(m_szTitle);
			m_szTitle = szTitle;
		}
		else
			return FALSE;
	}
	else
		memset(m_szTitle,0,m_nTitleSize);
	
	strcpy(m_szTitle,lpszTitle);

	return TRUE;
}

LRESULT RingDockBar::OnClose()
{
	if(m_child)
		m_child->Show(SW_HIDE);
	m_bVisible = FALSE;
	if(m_pSite)
		m_pSite->HideBar(this);
	return 0;
}

void RingDockBar::Show(int nState)
{
	if(nState == SW_SHOW || nState == SW_HIDE)
	{
		if(m_State == TBS_FLAG_FLY && m_flyBar)
			m_flyBar->Show(nState);
		else
		{
			if(m_child)
				m_child->Show(nState);
			m_bVisible = (nState == SW_SHOW);
			if(m_lineInfo && m_bVisible)
				m_lineInfo->isVisible = TRUE;
			UpdateAllSite();
		}
	}
}

LRESULT RingDockBar::OnSizing(RINGPARAMS& param)
{	
	RECT rc;
	LPRECT lprc = (LPRECT)param.lParam;
	//param.lParam = (LPARAM)&rc;
	CopyRect(&rc,lprc);

	if(m_child)
		SendMessage(m_child->Handle(),param.uMsg,param.wParam,param.lParam);
	
//	SetPos(0,0,lprc->right - lprc->left,lprc->bottom - lprc->top);

	AdjustSizingRect(param.wParam,lprc,rc);
	return TRUE;
}

void RingDockBar::AdjustSizingRect(int flag,LPRECT lprc,RECT& rc)
{
	switch(flag)
	{
		case WMSZ_LEFT:
		case WMSZ_BOTTOMLEFT:
			OffsetRect(lprc,rc.right - lprc->right,rc.top - lprc->top);
			break;
		case WMSZ_RIGHT:
		case WMSZ_BOTTOM:
		case WMSZ_BOTTOMRIGHT:
			OffsetRect(lprc,rc.left - lprc->left,rc.top - lprc->top);
			break;
		case WMSZ_TOP:
		case WMSZ_TOPRIGHT:
			OffsetRect(lprc,rc.left - lprc->left,rc.bottom - lprc->bottom);
			break;			
		case WMSZ_TOPLEFT:
			OffsetRect(lprc,rc.right - lprc->right,rc.bottom - lprc->bottom);
			break;
	}
}

//判断鼠标位于何方,本函数进入前已经过判断鼠标是在本DockBar范围内
UINT RingDockBar::HitTest(POINT* lpt)
{
	if((m_uStyle & TBS_EX_CANCLOSE) && PtInRect(&m_rcClose,*lpt))
		return HTCLOSE;
	else
		return HTCAPTION;
}

void RingDockBar::StartPushFrameControl(HWND hWnd,RingDragger* dragger,RINGPARAMS& param)
{
	if(m_CurWhere == HTCLOSE)
	{
		m_bNCBtDown = DFCS_CAPTIONCLOSE|DFCS_PUSHED;
		
		HDC hDC = GetDC(hWnd);
		DrawFrameControl(hDC,&m_rcClose,DFC_CAPTION,m_bNCBtDown);
		ReleaseDC(hWnd,hDC);
		
		SetCapture(hWnd);
	}
}

void RingDockBar::OnPushHoverFrameControl(HWND hWnd,RingDragger* dragger,LPPOINT lpt)
{
	if(m_CurWhere == HTCLOSE)
	{
		HDC hDC = GetDC(hWnd);
		
		if(PtInRect(&m_rcClose,*lpt))
		{
			if((m_bNCBtDown & DFCS_PUSHED)!= DFCS_PUSHED)
			{
				m_bNCBtDown |= DFCS_PUSHED;
				DrawFrameControl(hDC,&m_rcClose,DFC_CAPTION,m_bNCBtDown);
			}
		}
		else
		{
			if(m_bNCBtDown != DFCS_CAPTIONCLOSE)
			{
				m_bNCBtDown = DFCS_CAPTIONCLOSE;
				DrawFrameControl(hDC,&m_rcClose,DFC_CAPTION,DFCS_CAPTIONCLOSE);
			}
		}
		ReleaseDC(hWnd,hDC);
	}
}

void RingDockBar::StopPushFrameControl(HWND hWnd,RingDragger* dragger,LPPOINT lpt)
{
	if(PtInRect(&m_rcClose,*lpt) && m_CurWhere == HTCLOSE)
		OnClose();
}

//注意:hWnd有可能是FlyBar的hWnd
LRESULT RingDockBar::StartDrag(HWND hWnd,RingDragger* dragger,RINGPARAMS& param)
{
	POINT pt = {param.mousept.x,param.mousept.y};
	m_CurWhere = HitTest(&pt);
	
	if(m_CurWhere == HTCAPTION)
	{
		if(LOWORD(m_uStyle) <= TBS_EX_DOCKABLE)
		{
			m_bNCBtDown = 2;
			
			InitDragRects(hWnd,pt,(IsRectEmpty(&m_hrc) || !IsFloat()));
			m_currState = m_State;

			if(IsFloat())
				dragger->StartDrag(hWnd,pt.x,pt.y,&m_frc,3);
			else
			{
				if(IsVert())
					dragger->StartDrag(hWnd,pt.x,pt.y,&m_vrc,1);
				else
					dragger->StartDrag(hWnd,pt.x,pt.y,&m_hrc,1);
			}
		}
	}
	else
		StartPushFrameControl(hWnd,dragger,param);

	return 0;
}

LRESULT RingDockBar::StopDrag(HWND hWnd,RingDragger* dragger,RINGPARAMS& param)
{
	if(dragger && dragger->IsDragging())
	{
		RECT rc;
		CopyRect(&rc,dragger->StopDrag(hWnd,param.mousept.x,param.mousept.y));
		Dockto(m_currState,&rc);
	}
	else
	{
		POINT pt = {param.mousept.x,param.mousept.y};

		ReleaseCapture();
		m_bNCBtDown = 0;
		StopPushFrameControl(hWnd,dragger,&pt);
	}
	return 0;
}

//处理窗口拖动
LRESULT RingDockBar::OnDrag(HWND hWnd,RingDragger* dragger,RINGPARAMS& param)
{
	POINT pt = {param.mousept.x,param.mousept.y};

	if(dragger && dragger->IsDragging())
	{
		RECT rc;
		LPRECT lprc;
		
		CopyRect(&rc,dragger->GetCurrRect());
		//擦除旧矩形
		lprc = dragger->EraseRect(pt.x,pt.y);
/*
RECT rc1;
CopyRect(&rc1,&m_hrc);
MapWindowPoints(hWnd,HWND_DESKTOP,(LPPOINT)&rc1,2);
dragger->DrawRect(&rc1,1);
CopyRect(&rc1,&m_vrc);
MapWindowPoints(hWnd,HWND_DESKTOP,(LPPOINT)&rc1,2);
dragger->DrawRect(&rc1,1);
CopyRect(&rc1,&m_frc);
MapWindowPoints(hWnd,HWND_DESKTOP,(LPPOINT)&rc1,2);
dragger->DrawRect(&rc1,1);
*/
		//计算新旧矩形的偏移量
		rc.left = lprc->left - rc.left;
		rc.top = lprc->top - rc.top;
		//偏移三个矩形
		OffsetRect(&m_hrc,rc.left,rc.top);
		OffsetRect(&m_vrc,rc.left,rc.top);
		OffsetRect(&m_frc,rc.left,rc.top);
		
		//GetWindowRect(m_child->Parent()->Handle(),&rc);
		//MapWindowPoints(HWND_DESKTOP,hWnd,(LPPOINT)&rc,2);
		m_child->Parent()->GetClientRect(&rc);
		MapWindowPoints(m_child->Parent()->Handle(),hWnd,(LPPOINT)&rc,2);
		
		//AdjustDragRects(pt,&rc);

		ClientToScreen(hWnd,&pt);
		
		m_currState = CheckFloatRect(hWnd,lprc,pt);		
		dragger->DrawRect(SetDragRect(hWnd,dragger));
/*
CopyRect(&rc1,&m_hrc);
MapWindowPoints(hWnd,HWND_DESKTOP,(LPPOINT)&rc1,2);
dragger->DrawRect(&rc1,1);
CopyRect(&rc1,&m_vrc);
MapWindowPoints(hWnd,HWND_DESKTOP,(LPPOINT)&rc1,2);
dragger->DrawRect(&rc1,1);
CopyRect(&rc1,&m_frc);
MapWindowPoints(hWnd,HWND_DESKTOP,(LPPOINT)&rc1,2);
dragger->DrawRect(&rc1,1);
*/
	}
	else if(param.wParam == MK_LBUTTON)
		OnPushHoverFrameControl(hWnd,dragger,&pt);
	
	return 0;
}

int RingDockBar::SetDragRect(HWND hWnd,RingDragger* dragger)
{
	switch(m_currState)
	{
		case TBS_FLAG_FLY:
			dragger->SetDragRect(&m_frc,hWnd);
			return 3;
		case TBS_FLAG_DOCKLEFT:
		case TBS_FLAG_DOCKRIGHT:
			dragger->SetDragRect(&m_vrc,hWnd);
			break;
		case TBS_FLAG_DOCKTOP:
		case TBS_FLAG_DOCKBOTTOM:
			dragger->SetDragRect(&m_hrc,hWnd);
			break;			
	}
	return 1;
}

void RingDockBar::UpdateCaption()
{
	if(m_uStyle & TBS_EX_CANCLOSE)
	{
		if(IsVert())
		{
			m_rcClose.left = m_rcDockPos.right - 15;
			m_rcClose.top = m_rcDockPos.top + 3;
			m_rcClose.right = m_rcDockPos.right - 3;
			m_rcClose.bottom = m_rcDockPos.top + 15;
		}
		else
		{
			m_rcClose.left = m_rcDockPos.left + 3;
			m_rcClose.top = m_rcDockPos.top + 3;
			m_rcClose.right = m_rcDockPos.left + 15;
			m_rcClose.bottom = m_rcDockPos.top + 15;
		}
	}
}

void RingDockBar::OffsetDockPos(int x,int y)
{
	OffsetRect(&m_rcClient,x,y);
	OffsetRect(&m_rcDockPos,x,y);
}

BOOL RingDockBar::SetDockPos(int x,int y,int width/*=-999*/,int height/*=-999*/)
{
	if(m_child == NULL)
		return FALSE;

	OffsetDockPos(x - m_rcDockPos.left,y - m_rcDockPos.top);
	return TRUE;
}

void RingDockBar::UpdateFlyBkg()
{
	//SizeBar占满FlyBar,参数为TRUE可能引起闪烁
	if(m_State == TBS_FLAG_FLY && m_flyBar && m_child)
		InvalidateRect(m_child->Handle(),NULL,!IsSizeBar());
}

BOOL RingDockBar::DrawBkg(HDC hDC,LPRECT lprc/*=NULL*/)
{	
	RingDockSite* tmp = NULL;
	RECT rc;
	SIZE offset={0,0};
	
	if(m_State == TBS_FLAG_FLY)
	{
		if(m_flyBar && m_child)
		{
			RingWnd* parent;
		
			parent = (RingWnd*)m_child->Parent();			
			if(parent)
			{
				for(int i=0;i<4;i++)
				{
					tmp = parent->GetDockSite(i);
					if(tmp)
					{
						m_flyBar->GetClientRect(&rc);
						//GetWindowRect(m_flyBar->Handle(),&rc);
						MapWindowPoints(m_flyBar->Handle(),tmp->Handle(),(LPPOINT)&rc,2);
						offset.cx = rc.left;
						offset.cy = rc.top;
						OffsetRect(&rc,-rc.left,-rc.top);
						return tmp->DrawBkg(hDC,&rc,&offset);
					}
				}
			}
		}
	}
	else
		tmp = m_pSite;
		
	if(tmp)
	{		
		if(lprc == NULL)
		{
			//NCPAINT
			CopyRect(&rc,&m_rcClient);
			OffsetRect(&rc,-m_rcClient.left,-m_rcClient.top);
			lprc = &rc;
			//offset.cx = m_rcClient.left;
			//offset.cy = m_rcClient.top;
		}
/*		else
		{
			RingBaseWnd::GetClientRect(&rc);
			CopyRect(lprc,&rc);
			//offset.cx = m_winpos.x + m_rcClient.left;
			//offset.cy = m_winpos.y + m_rcClient.top;
		}
*/
		offset.cx = m_rcClient.left;
		offset.cy = m_rcClient.top;

		return tmp->DrawBkg(hDC,lprc,&offset);
	}
	return FALSE;
}

//////////////////////////////////////
//
//绘制矩形框及手柄,如果子窗口显示状态与m_bVisible不一致,不绘制,返回FALSE,
//调用着应该更新DockSite,因为有可能要进行工具栏重排
//
/////////////////////////////////////
BOOL RingDockBar::Draw(HDC hDC)
{
	BOOL bUpdate;	
	if(IsVisible(&bUpdate) && !bUpdate)
	{
		//可视且不更新才绘制
		DrawFrame(hDC);
		DrawGripper(hDC);
//		if(m_child)
//			m_child->Repaint();//InvalidateRect(m_child->Handle(),NULL,TRUE);
	}
	return !bUpdate;
}

void RingDockBar::DrawFrame(HDC hDC)
{
	if((m_uStyle & TBS_EX_ALLLINE) == TBS_EX_ALLLINE)
	{
		if(IsVert())
			DrawEdge(hDC,&m_rcDockPos,BDR_RAISEDINNER,BF_RECT);
		else
		{
			//if(m_pSite && m_pSite->)
			RECT rc = {m_rcDockPos.left,m_rcDockPos.top-1,m_rcDockPos.right,m_rcDockPos.top+1};
			DrawEdge(hDC,&rc,BDR_SUNKENOUTER,BF_TOP | BF_BOTTOM);
			OffsetRect(&rc,0,m_rcDockPos.bottom - m_rcDockPos.top);
			DrawEdge(hDC,&rc,BDR_SUNKENOUTER,BF_TOP | BF_BOTTOM);
		}
	}
	else if(LOWORD(m_uStyle) != TBS_EX_NONE)
		DrawEdge(hDC,&m_rcDockPos,BDR_RAISEDINNER,BF_RECT);
}

void RingDockBar::DrawGripper(HDC hDC)
{	
	if(LOWORD(m_uStyle) == TBS_EX_NONE)
		return;

	RECT rc;
	CopyRect(&rc,&m_rcDockPos);
	InflateRect(&rc,-1,-2);
	int x=0,y=0,bx=2,by=2;
	
	if(IsVert())
	{
		rc.bottom = rc.top + 3;
		OffsetRect(&rc,0,1);

		if((m_uStyle & TBS_EX_CANCLOSE))
		{
			rc.right -= 17;
			OffsetRect(&rc,0,3);
			bx = rc.right + 2;
		}
		y = 4;
	}
	else
	{
		rc.right = rc.left + 3;
		OffsetRect(&rc,1,0);

		if((m_uStyle & TBS_EX_CANCLOSE))
		{
			rc.top += 17;
			OffsetRect(&rc,3,0);
			by = rc.top - 15;
		}		
		x = 4;
	}
	DrawEdge(hDC,&rc,BDR_RAISEDINNER,BF_RECT);
	OffsetRect(&rc,x,y);
	DrawEdge(hDC,&rc,BDR_RAISEDINNER,BF_RECT);

	if((m_uStyle & TBS_EX_CANCLOSE))
	{
		rc.left = bx;
		rc.top = by;
		rc.right = rc.left + 14;
		rc.bottom = rc.top + 14;
		DrawFrameControl(hDC,&m_rcClose,DFC_CAPTION,DFCS_CAPTIONCLOSE);
	}
}

//返回与前面一个dockbar之间的空间距离,同时修正停靠坐标
//调用该函数前提必须是已停靠
int RingDockBar::GetPreSpace()
{
	int presize = 0;
	
	if(m_child && m_pSite && m_bVisible)
	{
		if(IsVert())
		{
			if(m_prev)
				presize = m_prev->m_rcDockPos.bottom;
			presize = m_rcDockPos.top - presize;
			if(!IsVisible())
				presize += (m_rcDockPos.bottom - m_rcDockPos.top);
		}
		else
		{
			if(m_prev)
				presize = m_prev->m_rcDockPos.right;
			presize = m_rcDockPos.left - presize;
			if(!IsVisible())
				presize += (m_rcDockPos.right - m_rcDockPos.left);
		}		
	}
	return presize;
}

/***************************************************************************
//
//调整停靠位置,nEdge为右边界,nPreSpace为前面可移动空间,工具栏
//超过右边界,应往前移,但移动距离不可超过可移动空间。
//本函数假设所有工具栏都不重叠
//
***************************************************************************/
HDWP RingDockBar::AdjustDockPosH(HDWP hdwp,int nEdge,int nPreSpace,BOOL bCanWrap)
{
	int nPrevLen,offset = 0;

	if(m_child && m_pSite && m_bVisible)
	{
		RECT rcp;
		CopyRect(&rcp,&m_rcClient);
		if(m_prev)
			nPrevLen = m_rcDockPos.left - m_prev->m_rcDockPos.right;

		if(m_rcDockPos.right > nEdge || m_pSite->IsSizeBarInLine(m_lineInfo))
		{
			offset = -min(m_rcDockPos.right - nEdge,nPreSpace);			
			OffsetDockPos(offset,0);
		}
		else if(nPreSpace < 0)
		{
			offset = -nPreSpace;
			OffsetDockPos(offset,0);
		}			
		UpdateCaption();

		hdwp = m_child->DefDeferWindowPos(hdwp,m_rcClient.left,m_rcClient.top,
			m_rcClient.right - m_rcClient.left,m_rcClient.bottom - m_rcClient.top,
			IsAllLineBar()?0:SWP_NOSIZE);
		if(EqualRect(&rcp,&m_rcClient) && m_State == TBS_FLAG_DOCKBOTTOM)
			InvalidateRect(m_child->Handle(),NULL,FALSE);

		if(m_prev)
		{
			nPreSpace -= nPrevLen;//min(offset,m_winpos.x - m_prev->m_winpos.right);
			hdwp = m_prev->AdjustDockPosH(hdwp,m_rcDockPos.left,nPreSpace,bCanWrap);
		}
	}
	return hdwp;
}

void RingDockBar::SetDockPos(HDWP hdwp)
{
	if(IsMenuBar())
		DeferWindowPos(hdwp,m_child->Handle(),0,m_rcClient.left,m_rcClient.top,
		m_rcClient.right - m_rcClient.left,m_rcClient.bottom - m_rcClient.top,
		SWP_NOZORDER|SWP_NOACTIVATE);//|SWP_NOREDRAW);
	else
		DeferWindowPos(hdwp,m_child->Handle(),0,m_rcClient.left,m_rcClient.top,0,0,
		SWP_NOZORDER|SWP_NOSIZE|SWP_NOACTIVATE);//|SWP_NOREDRAW);
}

/***************************************************************************
//
//调整停靠位置,nEdge为下边界,nPreSpace为上面可移动空间,工具栏
//超过下边界,应往上移,但移动距离不可超过可移动空间。
//本函数假设所有工具栏都不重叠
//
***************************************************************************/
HDWP RingDockBar::AdjustDockPosV(HDWP hdwp,int nEdge,int nPreSpace,BOOL bCanWrap)
{
	int nPrevLen,offset = 0;

	if(m_child && m_pSite && m_bVisible)
	{
		RECT rcp;
		CopyRect(&rcp,&m_rcClient);
		if(m_prev)
			nPrevLen = m_rcDockPos.top - m_prev->m_rcDockPos.bottom;

		if(m_rcDockPos.bottom > nEdge)
		{
			offset = -min(m_rcDockPos.bottom - nEdge,nPreSpace);
			OffsetDockPos(0,offset);
		}
		else if(nPreSpace < 0)
		{
			offset = -nPreSpace;
			OffsetDockPos(0,offset);
		}			
		UpdateCaption();
		//if(m_winpos.x > nEdge && bCanWrap)
		//	m_pSite->WrapBar(m_lineInfo,this,(m_next == NULL));
		//else

		hdwp = m_child->DefDeferWindowPos(hdwp,m_rcClient.left,m_rcClient.top,
			m_rcClient.right - m_rcClient.left,m_rcClient.bottom - m_rcClient.top,
			IsAllLineBar()?0:SWP_NOSIZE);
		if(EqualRect(&rcp,&m_rcClient) && m_State == TBS_FLAG_DOCKRIGHT)
			InvalidateRect(m_child->Handle(),NULL,FALSE);
		/*
		if(IsMenuBar())
			hdwp = DeferWindowPos(hdwp,m_child->Handle(),0,m_rcClient.left,m_rcClient.top,
						m_rcClient.right - m_rcClient.left,m_rcClient.bottom - m_rcClient.top,
						SWP_NOZORDER|SWP_NOACTIVATE|SWP_SHOWWINDOW);//|SWP_NOCOPYBITS|SWP_NOREDRAW);
		else
			hdwp = DeferWindowPos(hdwp,m_child->Handle(),0,m_rcClient.left,m_rcClient.top,0,0,
							SWP_NOZORDER|SWP_NOSIZE|SWP_NOACTIVATE|SWP_SHOWWINDOW);//|SWP_NOCOPYBITS|SWP_NOREDRAW);
		//InvalidateRect(m_child->Handle(),NULL,FALSE);
		*/
		if(m_prev && hdwp)
		{
			//if(offset < 0)
			//	offset = m_prev->m_winpos.right - m_winpos.x;
			nPreSpace -= nPrevLen;//min(offset,m_winpos.x - m_prev->m_winpos.right);
			hdwp = m_prev->AdjustDockPosV(hdwp,m_rcDockPos.top,nPreSpace,bCanWrap);
		}
		//else
		//	m_pSite->WrapBar(m_lineInfo,NULL,FALSE);
	}
	return hdwp;
}

//根据工具栏拖动时的矩形判断应该停靠在哪一边,lprc,pt均为屏幕坐标,
//返回停靠位置(上下左右或浮动)
int RingDockBar::CheckFloatRect(HWND hWnd,LPRECT lprc,POINT pt)
{
	RECT rcClient,rcCheck;
	
	//判断窗口区域
	GetWindowRect(m_child->Parent()->Handle(),&rcClient);
	
	if(!PtInRect(&rcClient,pt))
		return TBS_FLAG_FLY;	  //鼠标不在窗口内部,返回浮动

	RingDockSite* pSite;
	RECT rc[4];
	int i,state=TBS_FLAG_FLY,max=0,cmp,hrch,vrcw;
	RECT rcCmp;
	POINT lpt = {pt.x,pt.y};

	ScreenToClient(hWnd,&lpt);
	m_child->Parent()->GetClientRect(&rcClient);
	MapWindowPoints(m_child->Parent()->Handle(),hWnd,(LPPOINT)&rcClient,2);
	
	hrch = m_hrc.bottom - m_hrc.top;
	vrcw = m_vrc.right - m_vrc.left;

	for(i=0;i<4;i++)
	{
		pSite = ((RingWnd*)m_child->Parent())->GetDockSite(i);
		if(CanDock(i))
		{
			if(pSite)
			{
				GetWindowRect(pSite->Handle(),&rcCheck);
				if(PtInRect(&rcCheck,pt))
				{
					//鼠标在该区域,优先返回
					if(i != m_currState)
					{
						ScreenToClient(hWnd,&pt);
						AdjustRects(hWnd,pt,i);
					}
					return i;
				}
				MapWindowPoints(HWND_DESKTOP,hWnd,(LPPOINT)&rcCheck,2);
			}
			else
				CopyRect(&rcCheck,&rcClient);

			switch(i)
			{
			case TBS_FLAG_DOCKTOP:
				if(!pSite || rcCheck.top == rcCheck.bottom)
				{
					//该方向无DockSite或DockSite内无停靠栏,设置判断矩形为
					//与该方向停靠栏等宽/高,与客户区重叠1像素
					rcCheck.bottom = rcCheck.top + 1;
					rcCheck.top = rcCheck.bottom - (m_hrc.bottom - m_hrc.top);
				}
				//记录重叠区域
				if(m_currState == TBS_FLAG_FLY)
				{
					rcCmp.left = m_hrc.left;
					rcCmp.right = m_hrc.right;
					if(lpt.y > m_frc.top + hrch)
					{
						rcCmp.bottom = lpt.y + m_BorderSpace;
						rcCmp.top = rcCmp.bottom - hrch;
					}
					else
					{
						rcCmp.top = m_frc.top;
						rcCmp.bottom = rcCmp.top + hrch;
					}					
				}
				else
					CopyRect(&rcCmp,&m_hrc);
				break;
			case TBS_FLAG_DOCKBOTTOM:
				if(!pSite || rcCheck.top == rcCheck.bottom)
				{
					rcCheck.top = rcCheck.bottom - 1;
					rcCheck.bottom = rcCheck.top + (m_hrc.bottom - m_hrc.top);
				}
				if(m_currState == TBS_FLAG_FLY)
				{
					rcCmp.left = m_hrc.left;
					rcCmp.right = m_hrc.right;
					if(lpt.y < m_frc.bottom - hrch)
					{
						rcCmp.top = lpt.y - m_BorderSpace;
						rcCmp.bottom = rcCmp.top + hrch;
					}
					else
					{
						rcCmp.bottom = m_frc.bottom;
						rcCmp.top = rcCmp.bottom - hrch;
					}					
				}
				else
					CopyRect(&rcCmp,&m_hrc);
				break;
			case TBS_FLAG_DOCKLEFT:
				if(!pSite || rcCheck.left == rcCheck.right)
				{
					rcCheck.right = rcCheck.left + 1;
					rcCheck.left = rcCheck.right - (m_vrc.right - m_vrc.left);
				}
				if(m_currState == TBS_FLAG_FLY)
				{
					rcCmp.top = m_vrc.top;
					rcCmp.bottom = m_vrc.bottom;
					if(lpt.x > m_frc.left + vrcw)
					{
						rcCmp.right = lpt.x + m_BorderSpace;
						rcCmp.left = rcCmp.right - vrcw;
					}
					else
					{
						rcCmp.left = m_frc.left;
						rcCmp.right = rcCmp.left + vrcw;
					}
				}
				else
					CopyRect(&rcCmp,&m_vrc);
				break;
			case TBS_FLAG_DOCKRIGHT:
				if(!pSite || rcCheck.left == rcCheck.right)
				{
					rcCheck.left = rcCheck.right - 1;
					rcCheck.right = rcCheck.left + (m_vrc.right - m_vrc.left);
				}
				if(m_currState == TBS_FLAG_FLY)
				{
					rcCmp.top = m_vrc.top;
					rcCmp.bottom = m_vrc.bottom;
					if(lpt.x < m_frc.right - vrcw)
					{
						rcCmp.left = lpt.x - m_BorderSpace;
						rcCmp.right = rcCmp.left + vrcw;
					}
					else
					{
						rcCmp.right = m_frc.right;
						rcCmp.left = rcCmp.right - vrcw;
					}
				}
				else
					CopyRect(&rcCmp,&m_vrc);
				break;
			}
			//按重叠面积大小判断应该停靠何方
			IntersectRect(rc+i,&rcCmp,&rcCheck);
			if(!IsRectEmpty(rc+i))
			{
				cmp = (rc[i].right - rc[i].left) * (rc[i].bottom - rc[i].top);
				if(cmp > max)
				{
					max = cmp;
					state = i;
				}
			}
		}
	}
	
	if(state != m_currState)// || state == TBS_FLAG_FLY)
	{
		ScreenToClient(hWnd,&pt);
		AdjustRects(hWnd,pt,state);
	}

	return state;
}

/*
int RingDockBar::CheckFloatRect(HWND hWnd,LPRECT lprc,POINT pt)
{
	RECT rcClient,rcCheck;
	
	//判断窗口区域
	GetWindowRect(m_child->Parent()->Handle(),&rcClient);
	
	if(!PtInRect(&rcClient,pt))
		return TBS_FLAG_FLY;	  //鼠标不在窗口内部,返回浮动
	
	RingDockSite* pSite;
	RECT rc[4];
	int i,state=TBS_FLAG_FLY,max=0,cmp;
	LPRECT lprcCmp;
	
	m_child->Parent()->GetClientRect(&rcClient);
	MapWindowPoints(m_child->Parent()->Handle(),hWnd,(LPPOINT)&rcClient,2);
	
	for(i=0;i<4;i++)
	{
		pSite = ((RingWnd*)m_child->Parent())->GetDockSite(i);
		if(CanDock(i))
		{
			if(pSite)
			{
				GetWindowRect(pSite->Handle(),&rcCheck);
				if(PtInRect(&rcCheck,pt))
				{
					//鼠标在该区域,优先返回
					ScreenToClient(hWnd,&pt);
					AdjustRects(hWnd,pt,i);
					return i;
				}
				MapWindowPoints(HWND_DESKTOP,hWnd,(LPPOINT)&rcCheck,2);
			}
			else
				CopyRect(&rcCheck,&rcClient);
			
			if(!pSite || rcCheck.left == rcCheck.right || rcCheck.top == rcCheck.bottom)
			{
				//该方向无DockSite或DockSite内无停靠栏,设置判断矩形为
				//与该方向停靠栏等宽/高,与客户区重叠1像素
				if(i == 0)
				{					
					rcCheck.bottom = rcCheck.top + 1;
					rcCheck.top = rcCheck.bottom - (m_hrc.bottom - m_hrc.top);
				}
				else if(i == 1)
				{
					rcCheck.top = rcCheck.bottom - 1;
					rcCheck.bottom = rcCheck.top + (m_hrc.bottom - m_hrc.top);
				}
				else if(i == 2)
				{
					rcCheck.right = rcCheck.left + 1;
					rcCheck.left = rcCheck.right - (m_vrc.right - m_vrc.left);
				}
				else
				{
					rcCheck.left = rcCheck.right - 1;
					rcCheck.right = rcCheck.left + (m_vrc.right - m_vrc.left);
				}
			}
			if(i < 2)
				lprcCmp = &m_hrc;
			else
				lprcCmp = &m_vrc;
			
			IntersectRect(rc+i,lprcCmp,&rcCheck);
		}
		else
			SetRectEmpty(rc+i);
	}
	//按重叠面积大小判断应该停靠何方
	for(i=0;i<4;i++)
	{
		if(!IsRectEmpty(rc+i))
		{
			cmp = (rc[i].right - rc[i].left) * (rc[i].bottom - rc[i].top);
			if(cmp > max)
			{
				max = cmp;
				state = i;
			}
		}
	}
	//if(state != m_currState || state == TBS_FLAG_FLY)
	{
		ScreenToClient(hWnd,&pt);
		AdjustRects(hWnd,pt,state);
	}
	
	return state;
}
*/
//根据宽高参数返回客户区宽高
int RingDockBar::GetClientWidth(int width)
{
	if(IsHorz())
	{
		if(width == 0)	//==0表示采用父窗口宽度
		{
			if(m_pSite)
				width = ::ClientWidth(m_pSite->Parent()->Handle());
			else
				return 0;
		}
		return width - m_BorderSpace * 2 - m_GripperSpace;
	}
	else if(IsFloat())
	{
		if(width == 0)	//==0表示采用父窗口宽度
		{
			if(m_flyBar)
				width = ::ClientWidth(m_flyBar->Handle());
			else
				return 0;
		}
		else
			width += m_BorderSpace * 2;
		return width;
	}
	else
	{
		if(width == 0)
			width = m_rcDockPos.right - m_rcDockPos.left;
		return width - m_BorderSpace * 2;
	}
}

int RingDockBar::GetClientHeight(int height)
{
	if(IsVert())
	{
		if(height == 0)	//==0表示采用父窗口宽度
		{
			if(m_pSite)
			{
				RECT rc;
				m_pSite->Parent()->GetClientRect(&rc);
				height = rc.bottom - rc.top;
			}
			else
				return 0;
		}
		return height - m_BorderSpace * 2 - m_GripperSpace;
	}
	else
	{
		if(height == 0)
			height = m_rcDockPos.bottom - m_rcDockPos.top;
		return height - m_BorderSpace * 2;
	}
}

//设置停靠坞,如果已停靠,从原停靠坞脱离
BOOL RingDockBar::SetDockSite(RingDockSite* docksite)
{	
	if(docksite == NULL)
	{		
		//浮动,不能改变m_State的值,该值由DockFly用到且函数结束时设置
		if(m_pSite && m_State != TBS_FLAG_FLY && m_State != TBS_FLAG_NONE)
			m_pSite->DelBar(this,FALSE);

		//如果是SizeBar,SizeBar的该函数会改变窗口尺寸
		OnDockStateChange(m_State,TBS_FLAG_FLY);
		return TRUE;
	}
	else
	{		
		//docksite有效,取docksite的停靠位置
		int state = docksite->GetState();
		
		if(m_child)	//已设定子窗口
		{
			if(m_State == TBS_FLAG_FLY)
			{
				//原浮动,隐藏浮动栏
				if(m_flyBar)
					m_flyBar->Show(SW_HIDE);
			}
			else if(m_pSite && m_pSite != docksite)	//已有停靠窗口,脱离
				m_pSite->DelBar(this,FALSE);
			
			//设置子窗口的父窗口为docksite
			m_child->SetParent(docksite->Handle());
			
			int nOldState = m_State;
			m_State = state;
			m_pSite = docksite;

			if(!(nOldState == state || (IsVert() && ::IsVert(nOldState)) ||
				(IsHorz() && ::IsHorz(nOldState))))
				if(0 == SendMessage(m_child->Handle(),WM_DOCKSTATECHANGE,
						MAKELONG(nOldState,state),(LPARAM)m_child->Handle()))
				{
					//未处理,采用默认处理
					OnDockStateChange(nOldState,state);
				}
			
			UpdateSize();
			return TRUE;		
		}
	}
	return FALSE;
}

//lprc:屏幕坐标
BOOL RingDockBar::DockFly(LPRECT lprc/*=NULL*/)
{
	if(m_child == NULL)
		return FALSE;

	if(m_flyBar == NULL)
	{
		m_flyBar = new RingFlyBar(m_child->Parent());
		CopyRect(&m_ldrc,&m_rcDockPos);
		MapWindowPoints(m_pSite->Handle(),m_pSite->Parent()->Handle(),(LPPOINT)&m_ldrc,2);
	}

	if(m_flyBar)
	{
		//winpos与flybar窗口左上角对齐。
		//浮动时停靠栏与停靠在最上方状态相同,其top位置为1,因此垂直位置-1
		OffsetDockPos(-m_rcDockPos.left - WINVAR_FRAME_X,//m_BorderSpace,
							- m_rcDockPos.top - 1 - BARTOOLY);
		
		if(m_child->GetParent() == m_flyBar->Handle())
		{
			if(m_State != TBS_FLAG_FLY)
				m_pSite->RegFlyBar(this);

			m_State = TBS_FLAG_FLY;

			if(lprc)
			{
				m_flyBar->SetPos(lprc->left,lprc->top);
				CopyRect(&m_lfrc,lprc);
				if(m_pSite)
				{
					ScreenToClient(m_pSite->Parent()->Handle(),(LPPOINT)&m_lfrc);
					ScreenToClient(m_pSite->Parent()->Handle(),(LPPOINT)&m_lfrc+1);
				}
			}
			else
				CopyRect(&m_lfrc,&m_frc);

			m_flyBar->Show();
			InvalidateRect(m_child->Handle(),NULL,TRUE);			
			return TRUE;
		}
		else if(m_flyBar->Create(m_szTitle))
		{
			int nOldState = m_State;

			if(m_State != TBS_FLAG_FLY)
				m_pSite->RegFlyBar(this);
			m_State = TBS_FLAG_FLY;

			SendMessage(m_child->Handle(),WM_DOCKSTATECHANGE,
							MAKELONG(nOldState,TBS_FLAG_FLY),(LPARAM)m_child->Handle());
			
			if(lprc)
			{
				m_flyBar->SetPos(lprc->left,lprc->top);
				CopyRect(&m_lfrc,lprc);
				if(m_pSite)
				{
					ScreenToClient(m_pSite->Parent()->Handle(),(LPPOINT)&m_lfrc);
					ScreenToClient(m_pSite->Parent()->Handle(),(LPPOINT)&m_lfrc+1);
				}
			}
			else
				CopyRect(&m_lfrc,&m_frc);
			
			m_flyBar->AddChild(this);
			m_flyBar->Show();
			
			return TRUE;
		}
		else
		{
			delete m_flyBar;
			m_flyBar = NULL;
		}
	}
	return FALSE;
}

//////////////////////////////////////
//
//lprc:为父窗口的相对坐标
//
//////////////////////////////////////
BOOL RingDockBar::Dockto(int state,LPRECT lprc)
{
	if(m_child == NULL)
		return FALSE;

	//条件如果成立,表示停靠位置变动,设置DockSite
	if(m_State != state)
		SetDockSite(((RingWnd*)m_child->Parent())->CreateDockSite(state));
	
	if(state != TBS_FLAG_FLY)
	{
		//AddBar会更新所有DockSite尺寸
		if(m_pSite)
		{
			if(m_State == TBS_FLAG_FLY)
				m_pSite->UnregFlyBar(this);
			
			m_pSite->AddBar(this,lprc);
		}
	}
	else
	{
		RECT rc;

		if(lprc == NULL)
			CopyRect(&rc,&m_frc);
		else
		{
			CopyRect(&rc,lprc);
			ClientToScreen(m_child->Parent()->Handle(),(LPPOINT)&rc);
			ClientToScreen(m_child->Parent()->Handle(),(LPPOINT)&rc+1);
		}

		//更新DockSite尺寸
		if(m_State != TBS_FLAG_FLY && m_State != TBS_FLAG_NONE)
			m_pSite->UpdateAllSite();
				
		DockFly(&rc);
	}
	return TRUE;
}

int RingDockBar::DockBack()
{
	if(m_State == TBS_FLAG_FLY)
	{
		if(IsRectEmpty(&m_ldrc))
			Dockto(TBS_FLAG_DOCKTOP);
		else
			Dockto(m_pSite->GetState(),&m_ldrc);
	}
	else
	{
		CopyRect(&m_ldrc,&m_rcDockPos);
		MapWindowPoints(m_pSite->Handle(),m_pSite->Parent()->Handle(),(LPPOINT)&m_ldrc,2);
		//if(IsRectEmpty(&m_hrc))
		{
			POINT pt = {0,0};
			InitDragRects(m_pSite->Handle(),pt,TRUE);
		}
		Dockto(TBS_FLAG_FLY,&m_lfrc);
	}
	return GetState();
}

//初始化三个矩形
void RingDockBar::InitDragRects(HWND hWnd,POINT pt,BOOL bInit)
{
	if(bInit)
	{
		CopyRect(&m_hrc,GetDragRects(TBS_FLAG_HORZ));
		CopyRect(&m_vrc,GetDragRects(TBS_FLAG_VERT));
		CopyRect(&m_frc,GetDragRects(TBS_FLAG_FLY));
	}
	else
	{
		//CopyRect(&m_frc,GetDragRects(TBS_FLAG_FLY));
		OffsetRect(&m_hrc,m_rcDockPos.left-m_hrc.left,m_rcDockPos.top-m_hrc.top);
		OffsetRect(&m_vrc,m_rcDockPos.left-m_vrc.left,m_rcDockPos.top-m_vrc.top);
		OffsetRect(&m_frc,m_rcDockPos.left-m_frc.left,m_rcDockPos.top-m_frc.top);
	}
	RECT rc = {0,0,0,0};
	if(m_child)
		GetWindowRect(m_child->Parent()->Handle(),&rc);
	MapWindowPoints(HWND_DESKTOP,hWnd,(LPPOINT)&rc,2);
	InitAdjustRects(pt,&rc);	
}

void RingDockBar::AdjustDragRects(POINT& pt,LPRECT lprcCheck)
{
	//浮动状态,把hrc往上移对齐
	if(pt.y < (lprcCheck->top + lprcCheck->bottom)/2)
	{
		//鼠标在上半部分,上对齐
		OffsetRect(&m_hrc,m_frc.left - m_hrc.left,m_frc.top - m_hrc.top);
		if(!PtInRect(&m_hrc,pt))
			OffsetRect(&m_hrc,0,pt.y - m_hrc.bottom);
	}
	else
	{
		//鼠标在下半部分,下对齐
		OffsetRect(&m_hrc,m_frc.left - m_hrc.left,m_frc.bottom - m_hrc.bottom);
		if(!PtInRect(&m_hrc,pt))
			OffsetRect(&m_hrc,0,pt.y - m_hrc.top);
	}
}

void RingDockBar::InitAdjustRects(POINT& pt,LPRECT lprcCheck)
{
	//初始化对齐
	if(m_State == TBS_FLAG_FLY)
	//if(m_CurrState == TBS_FLAG_FLY)
	{		
		//浮动状态,把hrc往上移对齐
		if(pt.y < (lprcCheck->top + lprcCheck->bottom)/2)
		{
			//鼠标在上半部分,上对齐
			OffsetRect(&m_hrc,m_frc.left - m_hrc.left,m_frc.top - m_hrc.top);
			if(!PtInRect(&m_hrc,pt))
				OffsetRect(&m_hrc,0,pt.y - m_hrc.bottom);
		}
		else
		{
			//鼠标在下半部分,下对齐
			OffsetRect(&m_hrc,m_frc.left - m_hrc.left,m_frc.bottom - m_hrc.bottom);
			if(!PtInRect(&m_hrc,pt))
				OffsetRect(&m_hrc,0,pt.y - m_hrc.top);
		}
	}
	else if(IsVert())
	{
		//纵向
		if(pt.y < (lprcCheck->top + lprcCheck->bottom)/2)
		{
			//鼠标在上半部分,hrc与vrc左上角对齐
			OffsetRect(&m_hrc,m_vrc.left - m_hrc.left,m_vrc.top - m_hrc.top);
			if(!PtInRect(&m_hrc,pt))	//鼠标不在hrc范围,hrc底边与鼠标对齐
				OffsetRect(&m_hrc,0,pt.y - m_hrc.bottom + m_BorderSpace);
		}
		else
		{
			//鼠标在下半部分,hrc与vrc左下角对齐
			OffsetRect(&m_hrc,m_vrc.left - m_hrc.left,m_vrc.bottom - m_hrc.bottom);
			if(!PtInRect(&m_hrc,pt))	//鼠标不在hrc范围,hrc上边与鼠标对齐
				OffsetRect(&m_hrc,0,pt.y - m_hrc.left - m_BorderSpace);
		}
		//frc与vrc左上角对齐
		OffsetRect(&m_frc,m_vrc.left - m_frc.left,m_vrc.top - m_frc.top);
		if(!PtInRect(&m_frc,pt))
		{
			//鼠标不在frc范围,frc中线移至鼠标位置(纵向)
			OffsetRect(&m_frc,0,pt.y - (m_frc.bottom + m_frc.top)/2);
			if(!PtInRect(&m_frc,pt))
				//仍不在,frc中线移至鼠标位置(横向)
				OffsetRect(&m_frc,pt.x - (m_frc.right + m_frc.left)/2,0);
		}
	}
	else
	{		
		if(pt.x < (lprcCheck->right + lprcCheck->left)/2)
		{
			//鼠标在左半部分,左对齐
			OffsetRect(&m_vrc,m_hrc.left - m_vrc.left,m_hrc.top - m_vrc.top);
			if(!PtInRect(&m_vrc,pt))
				OffsetRect(&m_vrc,pt.x - m_vrc.right,0);
		}
		else
		{
			//鼠标在右半部分,右对齐
			OffsetRect(&m_vrc,m_hrc.right - m_vrc.right,m_hrc.top - m_vrc.top);
			if(!PtInRect(&m_vrc,pt))
				OffsetRect(&m_vrc,pt.x - m_vrc.left,0);
		}
		//frc与hrc左上角对齐
		OffsetRect(&m_frc,m_hrc.left - m_frc.left,m_hrc.top - m_frc.top);
		if(!PtInRect(&m_frc,pt))
		{
			//鼠标不在frc范围,frc中线移至鼠标位置(横向)
			OffsetRect(&m_frc,pt.x - (m_frc.right + m_frc.left)/2,0);
			if(!PtInRect(&m_frc,pt))
				//仍不在,frc中线移至鼠标位置(纵向)
				OffsetRect(&m_frc,0,pt.x - (m_frc.bottom + m_frc.top)/2);
		}
	}	
}

/*********************************************************
//
//调整三个矩形,state:即将变成的状态,m_CurrState为原状态
//
//调整规则:
//		矩形由停靠状态变为浮动状态,先调整m_frc,
//		然后需要调整横竖矩形
//		根据m_frc为横竖向(宽高比决定),如果高比较大
//		则根据鼠标在客户区位置:上半部分,m_hrc与m_frc
//		上对齐,下半部分下对齐。宽比较大,则判断左右
//
*********************************************************/
void RingDockBar::AdjustRects(HWND hWnd,POINT pt,int state)
{
	switch(state)
	{
	case TBS_FLAG_DOCKTOP:
		OffsetRect(&m_hrc,0,m_frc.top - m_hrc.top);
		if(!PtInRect(&m_hrc,pt))
			OffsetRect(&m_hrc,0,pt.y - m_hrc.bottom + m_BorderSpace);
		if(!PtInRect(&m_hrc,pt))
			OffsetRect(&m_hrc,m_frc.left - m_hrc.left,0);
		break;
	case TBS_FLAG_DOCKBOTTOM:
		OffsetRect(&m_hrc,0,m_frc.bottom - m_hrc.bottom);
		if(!PtInRect(&m_hrc,pt))
			OffsetRect(&m_hrc,0,pt.y - m_hrc.top - m_BorderSpace);
		if(!PtInRect(&m_hrc,pt))
			OffsetRect(&m_hrc,m_frc.left - m_hrc.left,0);
		break;
	case TBS_FLAG_DOCKLEFT:
		OffsetRect(&m_vrc,m_frc.left - m_vrc.left,0);
		if(!PtInRect(&m_vrc,pt))
			OffsetRect(&m_vrc,pt.x - m_vrc.right + m_BorderSpace,0);
		if(!PtInRect(&m_hrc,pt))
			OffsetRect(&m_vrc,0,m_frc.top - m_vrc.top);
		break;
	case TBS_FLAG_DOCKRIGHT:
		OffsetRect(&m_vrc,m_frc.right - m_vrc.right,0);
		if(!PtInRect(&m_vrc,pt))
			OffsetRect(&m_vrc,pt.x - m_vrc.left - m_BorderSpace,0);
		if(!PtInRect(&m_hrc,pt))
			OffsetRect(&m_vrc,0,m_frc.top - m_vrc.top);
		break;
	case TBS_FLAG_FLY:
		//if((m_frc.bottom - m_frc.top) > (m_frc.right - m_frc.left))
		if(::IsHorz(m_currState))
		{
			if(m_currState == TBS_FLAG_DOCKTOP)
			{
				OffsetRect(&m_frc,0,m_hrc.top - m_frc.top);
				if(!PtInRect(&m_frc,pt))
					OffsetRect(&m_frc,0,pt.y - m_frc.bottom + m_BorderSpace);
			}
			else if(m_currState == TBS_FLAG_DOCKBOTTOM)
			{
				OffsetRect(&m_frc,0,m_hrc.bottom - m_frc.bottom);
				if(!PtInRect(&m_frc,pt))
					OffsetRect(&m_frc,0,pt.y - m_frc.top - m_BorderSpace);
			}
			//上下移动后不在鼠标范围,左右移动至中线与鼠标对齐
			if(!PtInRect(&m_frc,pt))
				OffsetRect(&m_frc,pt.x - (m_frc.right - m_frc.left)/2,0);
			
			//frc已上下移动,调整vrc
			OffsetRect(&m_vrc,0,m_frc.top - m_vrc.top);
		}
		else
		{
			if(m_currState == TBS_FLAG_DOCKLEFT)
			{
				OffsetRect(&m_frc,m_vrc.left - m_frc.left,0);
				if(!PtInRect(&m_frc,pt))
					OffsetRect(&m_frc,pt.x - m_frc.right + m_BorderSpace,0);
			}
			else if(m_currState == TBS_FLAG_DOCKRIGHT)
			{
				OffsetRect(&m_frc,m_vrc.right - m_frc.right,0);
				if(!PtInRect(&m_frc,pt))
					OffsetRect(&m_frc,pt.x - m_frc.left - m_BorderSpace,0);
			}
				
			if(!PtInRect(&m_frc,pt))
				OffsetRect(&m_frc,pt.y - (m_frc.bottom - m_frc.top)/2,0);
			//frc已左右移动,调整hrc
			OffsetRect(&m_hrc,m_frc.left - m_hrc.left,0);
		}
	}
	/*原代码
	{
	//变为m_frc
	RECT rcCheck;
	m_child->Parent()->GetClientRect(&rcCheck);
	MapWindowPoints(m_child->Parent()->Handle(),hWnd,(LPPOINT)&rcCheck,2);
	
	  if((m_frc.bottom - m_frc.top) > (m_frc.right - m_frc.left))
	  {
	  if(state != m_currState)
	  {
	  if(m_currState == TBS_FLAG_DOCKTOP)
					OffsetRect(&m_frc,0,m_hrc.top - m_frc.top);
					else if(m_currState == TBS_FLAG_DOCKBOTTOM)
					OffsetRect(&m_frc,0,m_hrc.bottom - m_frc.bottom);
					
					  if(!PtInRect(&m_frc,pt))
					  OffsetRect(&m_frc,pt.x - (m_frc.right - m_frc.left)/2,0);
					  //frc已上下移动,调整vrc
					  OffsetRect(&m_vrc,0,m_frc.top - m_vrc.top);
					  }
					  //调整hrc
					  if(pt.y > (rcCheck.bottom + rcCheck.top)/2)
					  {
					  //鼠标在下半部分,下移m_hrc;
					  OffsetRect(&m_hrc,0,m_frc.bottom - m_hrc.bottom);
					  if(pt.y <= m_hrc.top)
					  OffsetRect(&m_hrc,0,pt.y - m_hrc.top - m_BorderSpace);
					  }
					  else
					  {
					  //鼠标在上半部分,上移m_hrc;
					  OffsetRect(&m_hrc,0,m_frc.top - m_hrc.top);
					  if(pt.y >= m_hrc.bottom)
					  OffsetRect(&m_hrc,0,pt.y - m_hrc.bottom + m_BorderSpace);
					  }
					  }
					  else
					  {
					  if(state != m_currState)
					  {
					  if(m_currState == TBS_FLAG_DOCKLEFT)
					  OffsetRect(&m_frc,m_vrc.left - m_frc.left,0);
					  else if(m_currState == TBS_FLAG_DOCKRIGHT)
					  OffsetRect(&m_frc,m_vrc.right - m_frc.right,0);
					  
						 if(!PtInRect(&m_frc,pt))
						 OffsetRect(&m_frc,pt.y - (m_frc.bottom - m_frc.top)/2,0);
						 //frc已左右移动,调整hrc
						 OffsetRect(&m_hrc,m_frc.left - m_hrc.left,0);
						 }
						 //调整vrc
						 if(pt.x > (rcCheck.right + rcCheck.left)/2)
						 {
						 //鼠标在右半部分,右移m_vrc;
						 OffsetRect(&m_vrc,m_frc.right - m_vrc.right,0);
						 if(pt.x <= m_vrc.left)
						 OffsetRect(&m_vrc,pt.x - m_vrc.left - m_BorderSpace,0);
						 }
						 else
						 {
						 //鼠标在左半部分,左移m_vrc;
						 OffsetRect(&m_vrc,m_frc.left - m_vrc.left,0);
						 if(pt.x >= m_vrc.right)
						 OffsetRect(&m_vrc,pt.x - m_vrc.right + m_BorderSpace,0);
						 }
						 }
						 }
	*/
}

BOOL RingDockBar::AdjustSizeChildH()
{
	int step;
	
	m_rcDockPos.left = 0;	
	m_rcDockPos.right = m_pSite->m_rcPos.right - m_pSite->m_rcPos.left;
	m_rcClient.left = m_BorderSpace + m_GripperSpace;
	m_rcClient.right = m_rcDockPos.right - m_BorderSpace;

	step = m_pSite->m_rcPos.right - m_pSite->m_rcPos.left - m_GripperSpace - m_BorderSpace*2;	
	step = m_child->OnParentNotify(NULL,MYWM_SIZE,step,TBS_FLAG_HORZ);
	m_nSize = step + m_BorderSpace * 2;
	
	if(m_lineInfo)
	{
		//纵向尺寸
		m_rcDockPos.top = m_lineInfo->m_pos;
		m_rcDockPos.bottom = m_rcDockPos.top + m_nSize;
		m_rcClient.top = m_rcDockPos.top + m_BorderSpace;
		m_rcClient.bottom = m_rcClient.top + step;

		step = m_nSize - m_lineInfo->m_maxSize;
		if(step != 0)
		{
			m_lineInfo->m_maxSize = m_nSize;
			if(m_pSite && m_State != TBS_FLAG_FLY)
				m_pSite->UpdateLine(m_lineInfo,step,FALSE);
		}
		return TRUE;
	}
	return FALSE;
}

BOOL RingDockBar::AdjustSizeChildV()
{
	int step;
	
	m_rcDockPos.top = 0;	
	m_rcDockPos.bottom = m_pSite->m_rcPos.bottom - m_pSite->m_rcPos.top;
	m_rcClient.top = m_BorderSpace + m_GripperSpace;
	m_rcClient.bottom = m_rcDockPos.bottom - m_BorderSpace;
	
	step = m_pSite->m_rcPos.bottom - m_pSite->m_rcPos.top - m_GripperSpace - m_BorderSpace*2;	
	step = m_child->OnParentNotify(NULL,MYWM_SIZE,step,TBS_FLAG_VERT);
	m_nSize = step + m_BorderSpace * 2;
	
	if(m_lineInfo)
	{
		//横向尺寸
		m_rcDockPos.left = m_lineInfo->m_pos;
		m_rcDockPos.right = m_rcDockPos.left + m_nSize;
		m_rcClient.left = m_rcDockPos.left + m_BorderSpace;
		m_rcClient.right = m_rcClient.left + step;
		
		step = m_nSize - m_lineInfo->m_maxSize;
		if(step != 0)
		{
			m_lineInfo->m_maxSize = m_nSize;
			if(m_pSite && m_State != TBS_FLAG_FLY)
				m_pSite->UpdateLine(m_lineInfo,step,FALSE);
		}
		return TRUE;
	}
	return FALSE;
}


BOOL RingDockBar::AdjustChildH(int)
{
	if(m_child && m_pSite && m_bVisible)
	{
		if(IsAllLineBar())
			return AdjustSizeChildH();

		if(m_lineInfo)
		{
			//纵向尺寸
			m_rcDockPos.top = m_lineInfo->m_pos;
			if(m_pSite->IsSizeBarInLine(m_lineInfo))
			{
				//有SizeBar
				if(m_prev == NULL || !m_prev->IsVisible())
					m_rcDockPos.left = 0;
				else
					m_rcDockPos.left = m_prev->m_rcDockPos.right;
			}
			UpdateSize();
		}
		return TRUE;
	}
	return FALSE;
}

BOOL RingDockBar::AdjustChildV(int)
{
	if(m_child && m_pSite && m_bVisible)
	{
		if(IsAllLineBar())
			return AdjustSizeChildV();
		
		if(m_lineInfo)
		{
			//横向尺寸
			m_rcDockPos.left = m_lineInfo->m_pos;
			if(m_pSite->IsSizeBarInLine(m_lineInfo))
			{
				//有SizeBar
				if(m_prev == NULL || !m_prev->IsVisible())
					m_rcDockPos.top = 0;
				else
					m_rcDockPos.top = m_prev->m_rcDockPos.bottom;
			}
			UpdateSize();
		}
		return TRUE;
	}
	return FALSE;
}

///////////////////////////////////////////////////////
//
//	RingAllLineBar
//
///////////////////////////////////////////////////////
RingAllLineBar::RingAllLineBar()
{
	m_bSetH = m_bSetV = FALSE;
}

BOOL RingAllLineBar::ResetDragRect(LPRECT lprc,int state)
{
	RECT rc = {0,0,0,0};
	NMHDR hdr;
	hdr.hwndFrom = m_child->Handle();
	hdr.code = state;
	hdr.idFrom = (UINT)m_child;
	
	if(SendMessage(m_child->Handle(),WM_GETDRAGRECTS,(WPARAM)&rc,(LPARAM)&hdr))
	{
		InflateRect(&rc,m_BorderSpace,m_BorderSpace);
			
		if(::IsVert(state))
			rc.top -= m_GripperSpace + m_BorderSpace;
		else
			rc.left -= m_GripperSpace + m_BorderSpace;
		
		OffsetRect(&rc,lprc->left-rc.left,lprc->top-rc.top);
		CopyRect(lprc,&rc);
		return TRUE;
	}
	return FALSE;
}

//重载函数,设置拖动矩形,返回矩形宽度
int RingAllLineBar::SetDragRect(HWND hWnd,RingDragger* dragger)
{
	if(m_currState != m_State)
	{
		//恢复原矩形
		if(m_child)
		{
			if(::IsVert(m_State) && !m_bSetV)
			{
				if(!m_bSetV)
					m_bSetV = ResetDragRect(&m_vrc,TBS_FLAG_DOCKRIGHT);
			}
			else
			{
				if(!m_bSetH)
					m_bSetH = ResetDragRect(&m_hrc,TBS_FLAG_DOCKBOTTOM);
			}			
		}
	}
	return RingDockBar::SetDragRect(hWnd,dragger);
}

LRESULT RingAllLineBar::StopDrag(HWND hWnd,RingDragger* dragger,RINGPARAMS& param)
{
	m_bSetH = m_bSetV = FALSE;
	return RingDockBar::StopDrag(hWnd,dragger,param);
}
/*
void RingAllLineBar::DrawFrame(HDC hDC)
{
	if(LOWORD(m_uStyle) != TBS_EX_NONE)
		if(IsVert())
			DrawEdge(hDC,(LPRECT)&m_winpos,BDR_RAISEDINNER,BF_RECT);
		else
			DrawEdge(hDC,(LPRECT)&m_winpos,BDR_RAISEDINNER,BF_BOTTOM|BF_TOP);
}
*/